const config = require('config.js');
Page({
  data: {
    inputTextValue: "",
    outputTextValue: "",
    recordingTime: 0, // 录音时长
    timer: null, // 计时器
    // tempFilePath: null, // 临时录音文件路径
    isRecording: false,
    isRecordingName: "实时翻译",
    isConnected: false,
    recorderManager: null,
    socketTask: null,
    bgColor: "#2cc6d1",

    languageSourceList: config.LANGUAGE_SOURCE_LIST,
    languageSourceCode: config.LANGUAGE_SOURCE_CODE,
    languageTargetList: config.LANGUAGE_TARGET_LIST,
    languageTargetCode: config.LANGUAGE_TARGET_CODE,
    sourceLanguageIndex: 1, // 默认选中文
    targetLanguageIndex: 1, // 默认选英文
    sourceCurrentLanguageName: '中文',
    sourceCurrentLanguageCode: 'zh',
    targetCurrentLanguageName: '英文',
    targetCurrentLanguageCode: 'en',

    audioPlayList: config.AUDIO_PLAY_LIST,
    isPlayAudioIndex: 0,
    isPlayAudioName: '开启',

    audioVoiceSelectList: config.AUDIO_VOICE_SELECT_LIST,
    selectVoiceIndex: 0,
    selectVoiceName: '女声',
    
    isShowSetModal: false,
    isShowPhotoModal: false,

    imagePath: '',  // 图片路径（空表示未拍摄/选择）
    status: '',      // 状态提示文字

    modalAnimation: {} // 新增动画对象
  },

  
  // 显示设置弹窗
  showSettingModal() {
    if(this.data.isRecording){
      wx.showToast({ title: "请先关闭语音实时翻译", icon: "none" });
      return
    }
    const animation = wx.createAnimation({
      duration: 300,
      timingFunction: 'ease-out'
    })
    this.animation = animation
    //animation.opacity(0).scale(0.95).step()
    this.setData({
      isShowSetModal: true,
      modalAnimation: animation.export()
    })
    // 执行动画
    setTimeout(() => {
      //animation.opacity(1).scale(1).step()
      this.setData({
        modalAnimation: animation.export()
      })
    }, 10)
  },
  
  // 隐藏设置弹窗
  hideSettingModal() {
    const animation = wx.createAnimation({
      duration: 200,
      timingFunction: 'ease-in'
    })
    this.animation = animation
    animation.opacity(0).scale(0.95).step()
    this.setData({
      modalAnimation: animation.export()
    })
    // 延迟隐藏弹窗
    setTimeout(() => {
      this.setData({
        isShowSetModal: false
      })
    }, 200)
  },

  // 显示拍照弹窗
  showPhotoModal() {
    if(this.data.isRecording){
      wx.showToast({ title: "请先关闭语音实时翻译", icon: "none" });
      return
    }
    const animation = wx.createAnimation({
      duration: 300,
      timingFunction: 'ease-out'
    })
    this.animation = animation
    //animation.opacity(0).scale(0.95).step()
    this.setData({
      isShowPhotoModal: true,
      modalAnimation: animation.export()
    })
    // 执行动画
    setTimeout(() => {
      //animation.opacity(1).scale(1).step()
      this.setData({
        modalAnimation: animation.export()
      })
    }, 10)
    this.requestCameraPermission();
  },
  
  // 隐藏拍照弹窗
  hidePhotoModal() {
    const animation = wx.createAnimation({
      duration: 200,
      timingFunction: 'ease-in'
    })
    this.animation = animation
    animation.opacity(0).scale(0.95).step()
    this.setData({
      modalAnimation: animation.export()
    })
    // 延迟隐藏弹窗
    setTimeout(() => {
      this.setData({
        isShowPhotoModal: false
      })
    }, 200)
  },

  // 请求相机权限
  requestCameraPermission() {
    console.log("尝试申请相机权限");
    wx.authorize({
      scope: 'scope.camera',
      success: () => {
        console.log('已获得相机权限')
      },
      fail: () => {
        this.setData({
          status: '需要相机权限才能拍照，请在设置中开启'
        })
        // 引导用户打开权限设置
        wx.showModal({
          title: '权限不足',
          content: '请允许相机权限以使用拍照功能',
          success: (res) => {
            if (res.confirm) {
              wx.openSetting()
            }
          }
        })
      }
    })
  },

  // 拍照（绑定到"拍照"按钮）
  takePhoto() {
    wx.showToast({
      title: "拍照翻译请求中...",
      icon: "loading",
      duration: 16000 // 若需长期显示，可设为0，然后手动关闭
    });
    const ctx = wx.createCameraContext()
    ctx.takePhoto({
      quality: 'high', // 高质量
      success: (res) => {
        this.setData({
          imagePath: res.tempImagePath, // 保存临时路径
          status: '拍照成功'
        })
        this.uploadImage();
      },
      fail: (err) => {
        console.error('拍照失败', err)
        this.setData({
          status: '拍照失败，请重试'
        })
      }
    })
    this.hidePhotoModal();
  },

  // 图片上传
  uploadImage() {
    if (!this.data.imagePath) {
      wx.showToast({
        title: '请先拍照或选择图片',
        icon: 'none',
        duration: 2000
      })
      return
    }

    this.setData({
      status: '正在上传...'
    })

    // 读取图片并转为base64
    wx.getFileSystemManager().readFile({
      filePath: this.data.imagePath,
      encoding: 'base64',
      success: (res) => {
        // 发送到服务器（替换为你的服务器地址）
        wx.request({
          url: config.URL_TRANSLATE_PHOTO, // 注意：开发时需开启"不校验合法域名"
          method: 'POST',
          header: {
            'Content-Type': 'application/json'
          },
          data: {
            image: res.data, // base64数据
            sourceLanguage: this.data.sourceCurrentLanguageCode,
            targetLanguage: this.data.targetCurrentLanguageCode,
            isPlayAudio: this.data.isPlayAudioIndex,
            audioVoice: this.data.selectVoiceIndex
          },
          success: (response) => {
            wx.hideToast();
            if (response.statusCode === 200 && response.data.success) {
              this.setData({
                inputTextValue: response.data.recognizeResult,
                outputTextValue: response.data.translateResult
              })
              this.saveTextLog(response.data.recognizeResult, response.data.translateResult);
              if(this.data.isPlayAudioIndex == 0){
                this.audioDecode(response.data.audioDataBase64);
              }
            } else {
              this.setData({
                status: `上传失败：${response.data.message || '服务器错误'}`
              })
            }
          },
          fail: (err) => {
            wx.hideToast();
            console.error('上传请求失败', err)
            this.setData({
              status: '上传失败，请检查网络或服务器'
            })
          }
        })
      },
      fail: (err) => {
        wx.hideToast();
        console.error('读取图片失败', err)
        this.setData({
          status: '读取图片失败，请重试'
        })
      }
    })
  },

  // 存储当前音频上下文
  innerAudioContext: null,
  // 存储当前使用的音频文件路径
  currentAudioPath: null,
  
  onTextInput(e) {
    this.setData({ inputTextValue: e.detail.value });
  },
  
  onSourceLangChange(e) {
    const index = e.detail.value;
    const Code = this.data.languageSourceCode[index];
    const Name = this.data.languageSourceList[index];
    this.setData({
      sourceLanguageIndex: index,
      sourceCurrentLanguageName: Name,
      sourceCurrentLanguageCode: Code
    });
  },

  onTargetLangChange(e) {
    const index = e.detail.value;
    const Code = this.data.languageTargetCode[index];
    const Name = this.data.languageTargetList[index];
    this.setData({
      targetLanguageIndex: index,
      targetCurrentLanguageName: Name,
      targetCurrentLanguageCode: Code
    });
  },

  onPlayAudioChange(e) {
    const index = Number(e.detail.value);
    const Name = this.data.audioPlayList[index];
    this.setData({
      isPlayAudioIndex: index,
      isPlayAudioName: Name,
    });
  },

  onSelectVoiceChange(e) {
    const index = Number(e.detail.value);
    const Name = this.data.audioVoiceSelectList[index];
    this.setData({
      selectVoiceIndex: index,
      selectVoiceName: Name,
    });
  },

  // 清理旧音频资源
  cleanOldAudio() {
    if (this.innerAudioContext) {
      this.innerAudioContext.stop();
      this.innerAudioContext.destroy();
      this.innerAudioContext = null;
      console.log("旧音频上下文已销毁");
    }
    if (this.currentAudioPath) {
      const fs = wx.getFileSystemManager();
      try {
        fs.unlinkSync(this.currentAudioPath);
        console.log(`旧音频文件已删除: ${this.currentAudioPath}`);
      } catch (err) {
        console.warn("删除旧音频文件失败:", err);
      }
      this.currentAudioPath = null;
    }
  },

  audioDecode(audioData) {
    this.setData({ isPlaying: false, loading: true });
    
    // 验证音频数据
    if (!audioData || typeof audioData !== 'string') {
      return this.handleAudioError("音频数据缺失或格式错误");
    }
  
    // 验证 Base64 格式
    if (!/^[A-Za-z0-9+/=]+$/.test(audioData)) {
      return this.handleAudioError("非法 Base64 字符串");
    }
    // 解码 Base64 数据
    const audioBytes = wx.base64ToArrayBuffer(audioData);
    
    this.audioHandler(audioBytes);
  },

  audioHandler(audioBytes) {
    if(this.data.isPlayAudioName == '关闭') return;
    // console.log("解码");
    try {
      // 生成唯一临时文件名
      const timestamp = new Date().getTime();
      const tempFilePath = `${wx.env.USER_DATA_PATH}/temp_audio_${timestamp}.mp3`;
      
      // 清理之前的音频上下文和临时文件
      this.cleanupAudioResources();
      
      // 保存当前音频路径
      this.currentAudioPath = tempFilePath;
      
      // 写入文件
      wx.getFileSystemManager().writeFile({
        filePath: tempFilePath,
        data: audioBytes,
        encoding: 'binary',
        success: () => {
          // 创建音频上下文
          this.innerAudioContext = wx.createInnerAudioContext();
          this.innerAudioContext.obeyMuteSwitch = false;
          this.innerAudioContext.src = tempFilePath;
          
          // 监听事件
          this.setupAudioListeners();
          
          // 准备播放
          this.innerAudioContext.play();
          this.setData({ isPlaying: true, loading: false });
        },
        fail: (err) => this.handleAudioError(`保存音频失败: ${err.errMsg}`)
      });
    } catch (e) {
      this.handleAudioError(`音频处理异常: ${e.message}`);
    }
  },
  
  // 统一错误处理
  handleAudioError(message) {
    console.error(message);
    this.setData({ loading: false, isPlaying: false });
    wx.showToast({ title: message, icon: "none" });
  },
  
  // 设置音频监听器
  setupAudioListeners() {
    // 移除旧监听（避免重复）
    this.innerAudioContext.offCanplay();
    this.innerAudioContext.offEnded();
    this.innerAudioContext.offError();
    
    // 监听音频加载完成
    this.innerAudioContext.onCanplay(() => {
      console.log("音频准备就绪");
      this.recorderManager.pause();
      if (this.data.loading) {
        this.setData({ loading: false });
      }      
    });
  
    // 监听播放结束
    this.innerAudioContext.onEnded(() => {
      console.log("音频播放结束");
      this.setData({ isPlaying: false });
      this.recorderManager.resume();
      this.scheduleFileCleanup();
    });
  
    // 监听错误
    this.innerAudioContext.onError(err => {
      this.handleAudioError(`播放失败: ${err.errMsg}`);
      this.scheduleFileCleanup();
    });
  },
  
  // 清理音频资源
  cleanupAudioResources() {
    // 销毁当前音频上下文
    if (this.innerAudioContext) {
      this.innerAudioContext.destroy();
      this.innerAudioContext = null;
    }
    
    // 安排清理旧临时文件（延迟执行，避免影响当前播放）
    this.scheduleFileCleanup();
  },
  
  // 安排临时文件清理
  scheduleFileCleanup() {
    // 使用 setTimeout 避免阻塞主线程
    setTimeout(() => {
      try {
        const fs = wx.getFileSystemManager();
        const dirPath = wx.env.USER_DATA_PATH;
        
        // 读取目录内容
        fs.readdir({
          dirPath,
          success: ({ files }) => {
            // 过滤出旧的音频文件（保留最近3个）
            const audioFiles = files
              .filter(file => file.startsWith('temp_audio_') && file.endsWith('.mp3'))
              .sort()
              .slice(0, -3); // 保留最近3个文件
              
            // 删除旧文件
            audioFiles.forEach(file => {
              fs.unlink({
                filePath: `${dirPath}/${file}`,
                fail: err => console.warn(`删除旧文件失败: ${file}`, err)
              });
            });
          },
          fail: err => console.warn('读取临时目录失败', err)
        });
      } catch (e) {
        console.warn('清理临时文件异常', e);
      }
    }, 5000); // 5秒后执行清理
  },
  
  // 控制音频播放
  togglePlayback() {
    if (!this.innerAudioContext) return;
    
    if (this.data.isPlaying) {
      this.innerAudioContext.pause();
    } else {
      this.innerAudioContext.play();
    }
    
    this.setData({ isPlaying: !this.data.isPlaying });
  },

  // 文本翻译
  handleTranslateText() {
    if(this.data.isRecording){
      wx.showToast({ title: "请先关闭语音实时翻译", icon: "none" });
      return
    }
    const { inputTextValue: text1Value } = this.data;
    if (!text1Value.trim()) {
      wx.showToast({ title: "请输入要翻译的内容", icon: "none" });
      return;
    }

    // 先清理旧资源，避免干扰
    this.cleanOldAudio();
    console.log(this.data.selectVoiceIndex, typeof this.data.selectVoiceIndex)

    wx.showToast({
      title: "文本翻译请求中...",
      icon: "loading",
      duration: 8000 // 设置为0，手动关闭
    });

    wx.request({
      url: config.URL_TRANSLATE_TEXT,
      method: "POST",
      header: { "Content-Type": "application/json" },
      data: {
        text: text1Value,
        from: this.data.sourceCurrentLanguageCode,
        to: this.data.targetCurrentLanguageCode,
        isPlayAudio: this.data.isPlayAudioIndex,
        audioVoice: this.data.selectVoiceIndex,
      },
      // responseType: 'arraybuffer',
      success: (res) => {
        wx.hideToast();
        // 检查响应格式
        
        if (!res.data || typeof res.data !== 'object') {
          try {
            res.data = JSON.parse(res.data);
          } catch (e) {
            console.error("JSON 解析失败:", res.data);
            wx.showToast({ title: "服务器响应格式错误", icon: "none" });
            return;
          }
        }
        // 检查翻译结果
        const { translatedText, audioData, error } = res.data;
        
        if (error || !translatedText) {
          wx.showToast({ title: error || "翻译失败", icon: "none" });
          return;
        }
        // 更新翻译文本
        this.setData({ 
          outputTextValue: translatedText || "" 
        });
        this.saveTextLog(this.data.inputTextValue ,translatedText);
        // 处理音频
        if(this.data.isPlayAudioIndex == 0){
          this.audioDecode(audioData);
        }
      },
      fail: (err) => {
        wx.hideToast();
        console.error("请求失败:", err);
        wx.showToast({ title: "网络错误", icon: "none" });
      }
    });
  },

  handleTranslatePhoto(){
    console.log("被点击");
  }, 

  onLoad() {
    // 初始化录音管理器
    this.recorderManager = wx.getRecorderManager();
    
    // 录音管理器事件监听
    this.recorderManager.onStart(() => {
      console.log('录音开始');
      this.setData({
        isRecording: true,
        isRecordingName: '停止录音',
        bgColor: 'red',
        status: "录音中..."
      });
    });

    this.recorderManager.onStop((res) => {
      console.log('录音停止', res);
      this.setData({ 
        isRecording: false,
        isRecordingName: '实时翻译',
        bgColor: '#2cc6d1',
      });
    });
    
    this.recorderManager.onPause(() =>{
      this.setData({
        status: "播放中..."
      })
    });

    this.recorderManager.onResume(() =>{
      this.setData({
        status: "录音中..."
      })
    });

    this.recorderManager.onFrameRecorded((res) => {
      const { frameBuffer, isLastFrame } = res;
      // 发送数据到服务器
      if (this.data.isConnected) {
        this.socketTask.send({
          data: frameBuffer,
          success: () => {
            //console.log('数据发送成功');
          },
          fail: (err) => {
            console.error('数据发送失败:', err);
          }
        });
      }
    });

    
  },
   
  handleTranslateRealTime(){
    console.log(this.data.isRecording);
    if(this.data.isRecording){
      this.stopRecording();
      return;
    }
    this.connectWebSocket();
    
  },


  connectWebSocket() {
    if (this.data.isConnected) {
      console.log('WebSocket已连接');
      return;
    }
    // 连接WebSocket服务器
    this.socketTask = wx.connectSocket({
      url: config.URL_TRANSLATE_REALTIME,
      success: () => {
        this.setData({ isConnected: true });
        console.log('WebSocket连接成功');
      },
      fail: (err) => {
        wx.showToast({ title: "WebSocket连接失败", icon: "none" });
        console.error('WebSocket连接失败:', err);
      }
    });

    // 监听WebSocket连接打开
    this.socketTask.onOpen(() => {
      console.log('WebSocket连接已打开');
      console.log('准备发送目标语音');
        // 准备要发送的数据
      const requestData = {
        from: this.data.sourceCurrentLanguageCode,
        to: this.data.targetCurrentLanguageCode,
        audioVoice: this.data.selectVoiceIndex
      };
      // 通过WebSocket发送数据
      this.socketTask.send({
        data: JSON.stringify(requestData), // 将对象转换为JSON字符串
        success: () => {
          console.log('已经发送目标语音');
        },
        fail: (err) => {
          console.error('数据发送失败:', err);
        }
      });
    });

    // 监听WebSocket消息
    this.socketTask.onMessage((res) => {
      console.log('收到服务器消息');
      if(res.data instanceof ArrayBuffer){
        this.audioHandler(res.data)
      }else{
        this.handleTextMessage(res.data);
      }
    });

    // 监听WebSocket错误
    this.socketTask.onError((err) => {
      wx.showToast({ title: "WebSocket错误", icon: "none" });
      console.error('监听到WebSocket错误:', err);
      this.setData({ isConnected: false });
    });

    // 监听WebSocket关闭
    this.socketTask.onClose(() => {
      wx.showToast({ title: "WebSocket连接已关闭", icon: "none" });
      console.log('WebSocket连接已关闭');
      this.setData({ isConnected: false });
    });
  },
  // 处理消息
  handleTextMessage(message) {
    try {
      // 将JSON字符串解析为JavaScript对象
      const result = JSON.parse(message);
      
      if(result.message_type == "OK"){
        this.startRecording();
        return
      }
        // 更新页面数据
      this.setData({
        inputTextValue: result.transcriptionWx,
        outputTextValue: result.translationWx
      });

      if(result.sentenceEnd){
        this.saveTextLog(result.transcriptionWx, result.translationWx);
      }
      // 在这里可以进行UI更新或其他业务逻辑
      
    } catch (error) {
      console.error('解析消息失败:', error);
    }
  },

  disconnectWebSocket() {
    if (!this.data.isConnected) {
      wx.showToast({ title: "WebSocket未连接", icon: "none" });
      console.log('WebSocket未连接');
      return;
    }
    
    // 停止录音
    if (this.data.isRecording) {
      this.recorderManager.stop();
    }
    
    // 关闭WebSocket连接
    if (this.socketTask) {
      this.socketTask.close({
        success: () => {
          console.log('WebSocket关闭成功');
        },
        fail: (err) => {
          console.error('WebSocket关闭失败:', err);
        }
      });
    }
  },

  startRecording() {
    
    // console.log("Rec", this.data.isConnected)
    if (!this.data.isConnected) {
      wx.showToast({
        title: '请先连接WebSocket',
        icon: 'none'
      });
      return;
    }
    
    if (this.data.isRecording) {
      console.log('正在录音中');
      return;
    }
    
    const options = {
      format: config.RECORD_OPTION_FORMAT,
      sampleRate: config.RECORD_OPTION_SAMPLE_RATE,
      numberOfChannels: config.RECORD_OPTION_NUMBER_OF_CHANNELS,
      encodeBitRate: config.RECORD_OPTION_ENCODE_BIT_RATE,
      frameSize: config.RECORD_OPTION_FRAME_SIZE, 
      duration: 600000, 
      // audioSource: 'communications'  // 选择适合通话的音频源
    };
    
    this.recorderManager.start(options);
    // this.setData({ isRecording: true, innerAudioContext });
  },

  stopRecording: function() {
    if (!this.data.isRecording) {
      console.log('未在录音');
      return;
    }
    
    this.recorderManager.stop();
    this.disconnectWebSocket();
  },

  saveTextLog(inText, outText){
    const inTxt = String(inText);
    const outTxt = String(outText);

    // 获取当前时间
    const date = new Date();
    const timeStr = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;

    // 创建新记录
    const newRecord = {
      inText: inTxt,
      outText: outTxt,
      time: timeStr
    };

    // 从本地存储获取现有记录
    const existingHistory = wx.getStorageSync('textRecords') || [];
    
    // 更新历史记录列表（新记录放在最前面）
    const newHistory = [newRecord, ...existingHistory];
    
    // 保存到本地存储
    wx.setStorageSync('textRecords', newHistory);
    
  },

  // 页面卸载时清理资源
  onUnload() {
    this.cleanOldAudio();
    clearInterval(this.data.timer);
    if (this.data.socketOpen) {
      wx.closeSocket();
    }
    wx.clearStorageSync();
  }
});